package com.neuronbit.businessflow.intellij.ui.projectView;

import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.refactoring.move.MoveHandlerDelegate;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesHandler;
import com.neuronbit.businessflow.intellij.BpmFileType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

/**
 * The type Flow move provider.
 */
public class FlowMoveProvider extends MoveHandlerDelegate {
    private static final Logger LOG = Logger.getInstance(FlowMoveProvider.class);

    @Override
    public boolean canMove(DataContext dataContext) {
        Flow[] flows = Flow.DATA_KEY.getData(dataContext);
        return flows != null && flows.length > 0;
    }

    @Override
    public boolean isValidTarget(PsiElement psiElement, PsiElement[] sources) {
        return MoveFilesOrDirectoriesHandler.isValidTarget(psiElement);
    }

    @Override
    public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
        return false;
    }

    @Override
    public void collectFilesOrDirsFromContext(DataContext dataContext, Set<PsiElement> filesOrDirs) {
        Flow[] flows = Flow.DATA_KEY.getData(dataContext);
        LOG.assertTrue(flows != null);
        PsiClass[] classesToMove = new PsiClass[flows.length];
        PsiFile[] filesToMove = new PsiFile[flows.length];
        for(int i = 0; i< flows.length; i++) {
            classesToMove [i] = flows[i].getClassToBind();
            if (classesToMove[i] != null) {
                final PsiFile containingFile = classesToMove[i].getContainingFile();
                if (containingFile != null) {
                    filesOrDirs.add(containingFile);
                }
            }
            filesToMove [i] = flows[i].getFormFiles() [0];
            if (filesToMove[i] != null) {
                filesOrDirs.add(filesToMove[i]);
            }
        }
    }


    @Override
    public boolean isMoveRedundant(PsiElement source, PsiElement target) {
        if (source instanceof PsiFile && source.getParent() == target) {
            final VirtualFile virtualFile = ((PsiFile)source).getVirtualFile();
            if (virtualFile != null && virtualFile.getFileType() instanceof BpmFileType) {
                return true;
            }
        }
        return super.isMoveRedundant(source, target);
    }

    @Override
    public boolean supportsLanguage(@NotNull Language language) {
        return false;  // only available in project view
    }
}

